#!/usr/bin/python
import sys
import gobject
import threading
import os
import datetime # for preferences (should this be moved to backend?)
import pdb #python debugger.
import subprocess

import imp
# for win compatibility
#requires import imp, os, sys
#returns True when running from the exe
def main_is_frozen():
       return (hasattr(sys, "frozen") or # new py2exe
               hasattr(sys, "importers") # old py2exe
               or imp.is_frozen("__main__")) # tools/freeze

#Returns path of exe
def get_main_dir():
       if main_is_frozen():
               return os.path.dirname(sys.executable)
       return os.path.dirname(sys.argv[0])

if main_is_frozen():
       PROJECT_ROOT = get_main_dir()
else:
       PROJECT_ROOT = os.path.dirname(os.path.realpath(__file__))
 
sys.path.append(PROJECT_ROOT)

import backend as backend
import pygtk
pygtk.require("2.0")
import gtk

gobject.threads_init()

class ImportThread(threading.Thread):
	def __init__(self, guiObject, selected_files):
		super(ImportThread, self).__init__()
		self.gui = guiObject
		self.selected_files = selected_files

	# Callback function for backend
	def backend_progress(self, status, thumb_pixbuf, percent_complete):
		if backend.QUIT_IMPORT: 
			return False
		self.gui.thumbnail_preview.set_from_pixbuf(thumb_pixbuf)
		self.gui.main_progressbar.set_fraction(percent_complete)
		self.gui.label_browser_status.set_label(status)
		return False
	
	#Callback function for backend finishing
	def backend_finished(self, numFilesImported, errorLog):
		self.gui.setImportNotRunningGUI()
		self.gui.label_browser_status.set_label("Completed import")

		successText = "\nImported "+ str(numFilesImported) + " files"
		self.gui.label_report_log.set_label(successText + "\n\n" + errorLog)
		self.gui.label_report_title.set_label("Import Results:")

		if backend.prefs["deleteMedia"]:
			self.gui.fill_thumb_browser()
		
		#reload icons if there was an error
		if errorLog:
			self.gui.fill_thumb_browser()
		
		return False

	def run(self):
		backend.Import(self.backend_progress, self.backend_finished, self.selected_files)


class BrowserThread(threading.Thread):
	def __init__(self, guiObject):
		super(BrowserThread, self).__init__()
		self.gui = guiObject
		theme = gtk.icon_theme_get_default()
		#self.defaultIcon = theme.load_icon(gtk.STOCK_ORIENTATION_LANDSCAPE, 100, 0)
		imagePath = os.path.join(PROJECT_ROOT,"graphics/frame.png")
		imagePath = os.path.normpath(imagePath) # cleans up path and make's it cross-platform
		self.defaultIcon = gtk.gdk.pixbuf_new_from_file(imagePath)

	def backend_filecount(self, fileSlice, isComplete):
		self.gui.liststore_files.extend(fileSlice)
		for f in fileSlice:
			name = os.path.split(f)[1]
			self.gui.liststore_browser.append([name, self.defaultIcon])

		if isComplete:
			self.gui.fileBrowseCount = len(self.gui.liststore_files)
			self.gui.set_status_total_filecount()

	def backend_thumb_file(self, restartCount, fullpath, name, icon):
		#Check if an update from an old thread
		if self.gui.numberBrowserThreadRestarts != restartCount:
			return

		#self.gui.liststore_files.append(fullpath)
		if not icon is None:
			try:
				index = self.gui.liststore_files.index(fullpath)
				treeModelRow = self.gui.liststore_browser[index]
				treeModelRow[1] = icon
			except:
				print "skipping thumb for ", fullpath

		#if self.gui.button_ShowOptions.get_active():
		#	txt="Showing "+str(len(self.gui.liststore_files))+" out of "+self.gui.fileBrowseCount
		#	self.gui.label_browser_status.set_label(txt)

	def run(self):
		backend.getBrowserFiles(0, self.backend_filecount, self.backend_thumb_file)

class ThumbnailThread(threading.Thread):
	def __init__(self, guiObject, filepath):
		super(ThumbnailThread, self).__init__()
		self.gui = guiObject
		self.filepath = filepath

	def backend_info(self, infoString):
		self.gui.label_thumb_caption.set_label(infoString)
		self.gui.showThumbPreview()

	def backend_thumb(self, thumb_pixbuf):
		self.gui.thumbnail_preview.set_from_pixbuf(thumb_pixbuf)

	def run(self):
		backend.getThumbAndInfo(self.filepath, self.backend_info, self.backend_thumb)

class GUI:
	# Main Window
	def gtk_main_quit(self, window):
		self.clean_up()
		gtk.main_quit()
		sys.exit()
	
	def on_Import_clicked(self, button):
		self.setImportRunningGUI()

		selected_files = self.getSelectedFiles()

		self.importThread = ImportThread(self, selected_files);
		self.importThread.start()

	def on_Cancel_clicked(self, button):
		if self.ImportRunning is False:
			self.clean_up()
			sys.exit()
		else:
			backend.QUIT_IMPORT = True
			self.setImportNotRunningGUI()
			self.label_browser_status.set_label("Canceled import")

	
	def on_button_ShowOptions_toggled(self, button):
		if button.get_active():
			self.on_iconview_thumb_selection_changed(None)
			self.frame_browser.show()
			self.vbox_options.show()
			self.menubar.show()
			button.set_label("Hide Options")
			self.label_report_log.set_label("")	
			self.label_report_title.set_label("")
			if self.fill_thumb_browser_has_run is False:
				self.fill_thumb_browser()
		else:
			self.set_status_total_filecount()
			self.frame_browser.hide()
			self.vbox_options.hide()
			self.menubar.hide()
			self.expander_metadata.hide()
			self.window.resize(400,300)
			button.set_label("Show Options")
				
	#-------------------------------
	#Check Boxes, file choosers, rename text entry box
	def on_chk_photos_toggled(self, button):		
		backend.prefs["importPhotos"] = button.get_active()
		self.fill_thumb_browser()
		self.prefs_button_savePrefs.set_sensitive(True)
		
		
	def on_chk_videos_toggled(self, button):		
		backend.prefs["importVideos"] = button.get_active()
		self.fill_thumb_browser()
		self.prefs_button_savePrefs.set_sensitive(True)
		
	def on_chk_delete_toggled(self, button):
		backend.prefs["deleteMedia"] = button.get_active()
		self.prefs_button_savePrefs.set_sensitive(True)
		
	def on_chk_rename_toggled(self, button):
		backend.prefs["rename"] = button.get_active()
		self.entry_rename.set_visible(button.get_active())
		self.hbox_subDir_label.set_visible(self.chk_rename.get_active() or self.chk_subDir.get_active()) # show dir path example label
		if not button.get_active():
			self.entry_rename.set_text("")
			backend.prefs["renameString"] = ""
		self.prefsUpdatePathLabels() #update label text
		self.prefs_button_savePrefs.set_sensitive(True)
		
	def on_chk_subDir_toggled(self, button):
		self.entry_subDirName.set_visible(button.get_active()) # show text entry box
		self.hbox_subDir_label.set_visible(self.chk_rename.get_active() or self.chk_subDir.get_active()) # show dir path example label
		backend.GROUP_SUBDIR_NAME = self.entry_subDirName.get_text()
		self.on_entry_subDirName_changed(None) #set label text
		if not button.get_active():
			backend.GROUP_SUBDIR_NAME = None
		self.prefsUpdatePathLabels() #update label text
		self.prefs_button_savePrefs.set_sensitive(True)
		
	def on_photo_source_file_set(self, fileBrowser):
		if self.photo_source_firsttime:
			self.photo_source_firsttime = False
		else:
			if backend.prefs["sourceDir"] != os.path.normpath(fileBrowser.get_current_folder()):
				backend.prefs["sourceDir"] = os.path.normpath(fileBrowser.get_filename())
				self.fill_thumb_browser()
			self.prefs_button_savePrefs.set_sensitive(True)
		#re-enable import button if source folder is changed
		# should this be 'self.importThread.set_GUI_to_import()' instead?
		#self.btn_Import.set_sensitive(True)
		#self.btn_Cancel.set_label("Close")
		
		
	# TODO: allows blank rename string (if someone wants to rename to just img seq numbers)
	def on_entry_rename_changed(self, textBox):
		name = self.legalFilename(textBox.get_text())
		backend.prefs["renameString"] = name
		self.prefsUpdatePathLabels() #update label text
		textBox.set_text(name) # sets the text in gui to the clean filename (without illegal chars)
		self.prefs_button_savePrefs.set_sensitive(True)
		
	def on_entry_subDirName_changed(self, textEntry):
		dirName = self.legalFilename(self.entry_subDirName.get_text()) #checks for illegal chars
		backend.GROUP_SUBDIR_NAME = dirName
		if not dirName:
			backend.GROUP_SUBDIR_NAME = None
		self.entry_subDirName.set_text(dirName) #sets gui to clean char (no illegal chars)
		self.prefsUpdatePathLabels()
		self.prefs_button_savePrefs.set_sensitive(True)
		
	def on_rename_activate(self, textbox):
		self.setPrefs()
	#-------------------------------[End: Check Boxes, file choosers, rename text entry box]


	#-------------------------------
	# Icon Viewer:
	def on_iconview_thumb_selection_changed(self, view):
		selected = self.iconview_thumb.get_selected_items()
		if len(selected) == 1:
			filepath = self.liststore_files[selected[0][0]]
			thumbThread = ThumbnailThread(self, filepath);
			thumbThread.start()
			self.expander_metadata.show()
		else:
			self.label_thumb_caption.set_label("")
			self.thumbnail_preview.set_from_pixbuf(None)	
			self.showReport()
			self.expander_metadata.hide()

		if len(selected) > 0:
			self.label_browser_status.set_label(str(len(selected)) + " files selected")
			self.button_delete.set_visible(True)
		else:
			self.set_status_total_filecount()
			self.button_delete.set_visible(False)
	
	#double click on an icon		
	def on_iconview_thumb_item_activated(self, pixbuf, listIndex):
		path = self.liststore_files[listIndex[0]]
		
		try: #linux
			subprocess.Popen(["xdg-open", path])
		except:
			pass
		
		try: #Windows
			os.startfile(path)
		except:
			pass
	#-------------------------------[End: Icon Viewer]


	#-------------------------------
	# Top Menu Bar:
	def on_menuitem_quit_activate(self, menuitem):
		sys.exit()
	
	def on_menuitem_save_prefs_activate(self, menuitem):
		self.on_prefs_button_savePrefs_clicked(None)
	
	def on_menuitem_prefs_activate(self, menuitem):
		self.updatePrefsGui()
		self.dialog_preferences.run()
		self.dialog_preferences.hide()
		
	def on_menuitem_about_activate(self, menuitem):
		self.aboutdialog.run()
	#-------------------------------[End: Top Menu Bar]
	
	
	#-------------------------------
	# About Dialog
	
	#close the dialog box. not sure what the integer does, but it's needed
	def on_aboutdialog_close(self, widget, integer):
		widget.hide()
	#-------------------------------[End: About Dialog]
	
	
	#-------------------------------
	# Preference Dialog	
	def on_prefs_button_savePrefs_clicked(self, button):
		backend.savePrefs()
		self.prefs_button_savePrefs.set_sensitive(False)
		
	#this is run everytime a widget loses focus (gtk.Widget.focus-out-event)
	def on_prefs_lose_focus(self, widget, event):
		self.setPrefs()
	
	# generic helper function that gets called for error checking whenever a pref is set
	def setPrefs(self):
		#error checking - if it's left blank, the last saved value is used:
		if not backend.stringTuple(self.prefs_entry_imageExtensions.get_text()):
			self.prefs_entry_imageExtensions.set_text(backend.stringTuple(backend.prefs["photoExtensions"]))
		if not backend.stringTuple(self.prefs_entry_videoExtensions.get_text()):
			self.prefs_entry_videoExtensions.set_text(backend.stringTuple(backend.prefs["videoExtensions"]))
		if not self.prefs_entry_numPadding.get_text() or not self.prefs_entry_numPadding.get_text().isdigit():
			self.prefs_entry_numPadding.set_text(str(backend.prefs["renameStringNumPadding"]))
		try:
			datetime.date.today().strftime(self.prefs_entry_monthDir.get_text()) #test to see if syntax is valid
		except:
			self.prefs_entry_monthDir.set_text(backend.prefs["monthDirFormat"])
		if not self.prefs_entry_monthDir.get_text():
			self.prefs_entry_monthDir.set_text(backend.prefs["monthDirFormat"])
		
		# Updating Backend Prefs
		backend.prefs["photoExtensions"] = backend.stringTuple(self.prefs_entry_imageExtensions.get_text())
		backend.prefs["videoExtensions"] = backend.stringTuple(self.prefs_entry_videoExtensions.get_text())
		backend.prefs["renameStringNumPadding"] = int(self.prefs_entry_numPadding.get_text())
		backend.prefs["renameStringNumPaddingSeparator"] = self.prefs_entry_paddingSeparator.get_text()
		backend.prefs["monthDirFormat"] = self.prefs_entry_monthDir.get_text()
		#remove lead/trail spaces and trailing '.' for os compatibility		
		backend.prefs["renameString"] = self.legalFilenameHelper(self.entry_rename.get_text())
		backend.GROUP_SUBDIR_NAME = self.legalFilenameHelper(self.entry_subDirName.get_text())
		
		#update GUI
		self.updatePrefsGui()
		
	def on_extensions_changed(self, textEntry):
		self.prefs_button_savePrefs.set_sensitive(True)
	
	# prefs update if user changes file extension pref and then hits enter (same thing happens if they leave the textBox)
	def on_extension_entry_activate(self, textEntry):
		self.setPrefs()
	
	#Change the default Photo Library
	def on_photo_library_file_set(self, fileBrowser):
		if self.photo_library_firsttime:
			self.photo_library_firsttime = False
			self.prefs_button_savePrefs.set_sensitive(False) #disable 'save prefs' button
		else:
			backend.prefs["photoLibraryPath"] = fileBrowser.get_filename()
			self.prefs_button_savePrefs.set_sensitive(True) #re-enable 'save prefs' button
		self.prefsUpdatePathLabels()
		
	def on_prefs_button_close_activate(self, button): 
		self.dialog_preferences.hide()

	# update the example label when changing rename preferences
	def on_prefs_label_renameOptions_text_update(self, textEntry):
		#Error Checking:
		if not textEntry.get_text(): return # if either field is empty
		if not self.prefs_entry_numPadding.get_text().isdigit(): return
		if int(self.prefs_entry_numPadding.get_text()) > 10: # max number is 10
			self.prefs_entry_numPadding.set_text("10")
		name = self.labelFileName("photo", 1)
		
		self.prefsUpdatePathLabels() # sets path label
		self.prefs_button_savePrefs.set_sensitive(True) #re-enable 'save prefs' button
	
	def on_prefs_entry_monthDir_changed(self, widget):
		self.prefsUpdatePathLabels()
		self.prefs_button_savePrefs.set_sensitive(True)
		
	# update the example label when changing dir structure preferences
	def prefsUpdatePathLabels(self):
		if not self.prefs_entry_monthDir.get_text() or not self.photoLibraryPath(): return
		path = self.photoLibraryPath()
		name = backend.fileName("photo.jpg",1)
		renameExample = self.labelFileName()
		
		self.prefs_label_DirPath_text.set_text('"'+os.path.join(path, renameExample)+'"')
		
		self.label_subDir_text.set_text('"'+os.path.join(path, name)+'"')

		
	# reset prefs to default vaules
	def on_prefs_button_defaults_clicked(self, button):
		backend.prefs = backend.defaultPrefs()
		backend.GROUP_SUBDIR_NAME = None
		self.updatePrefsGui()
		self.prefs_button_savePrefs.set_sensitive(True) #re-enable 'save prefs' button
	
	#update the gui to reflect the backend variables
	def updatePrefsGui(self):
		self.prefs_entry_imageExtensions.set_text(backend.stringTuple(backend.prefs["photoExtensions"]))
		self.prefs_entry_videoExtensions.set_text(backend.stringTuple(backend.prefs["videoExtensions"]))
		self.prefs_entry_numPadding.set_text(str(backend.prefs["renameStringNumPadding"]))
		self.prefs_entry_paddingSeparator.set_text(backend.prefs["renameStringNumPaddingSeparator"])
		self.prefs_entry_monthDir.set_text(backend.prefs["monthDirFormat"])
		self.photo_library_browser.set_current_folder(backend.prefs["photoLibraryPath"])
		self.photo_source_browser.set_current_folder(backend.prefs["sourceDir"])
		
		self.chk_photos.set_active(backend.prefs["importPhotos"])
		self.chk_videos.set_active(backend.prefs["importVideos"])
		self.chk_delete.set_active(backend.prefs["deleteMedia"])
		self.chk_rename.set_active(backend.prefs["rename"])
		
		self.entry_rename.set_text(backend.prefs["renameString"])
		self.entry_subDirName.set_text(backend.GROUP_SUBDIR_NAME or "")	
		
		self.prefsUpdatePathLabels() # update the UI
	#-------------------------------[End: Preference Dialog]
	
	
	#-------------------------------
	# Delete photos Buttons
	def on_button_delete_clicked(self, button):	
		selected = self.iconview_thumb.get_selected_items()
		if len(selected) <= 0:
			self.label_browser_status.set_label("Select files to delete")			
			return
		
		#show_hide = True # if a widget is set to sensitive or not
		
		#Pushed the Delete button	
		if self.button_delete.get_label() == "Delete":
			self.showWhileDeleting(False)
			self.label_browser_status.set_label("Delete %s Photos?" % (len(selected)))
					
		#Pushed the Cancel button	
		elif self.button_delete.get_label() == "Cancel":
			self.set_status_total_filecount()
			self.showWhileDeleting(True)

		
	def on_button_delete_confirmation_clicked(self, button):
		errorfiles = backend.deleteFiles(self.getSelectedFiles())
		#TODO something with error files
		if len(errorfiles) > 0:
			print "Error deleting:", errorfiles
		self.fill_thumb_browser()
		self.showWhileDeleting(True)
		
		self.set_status_total_filecount()
	
	
	#-------------------------------
	# Helper functions
	
	def set_status_total_filecount(self):
		if self.fileBrowseCount is None:
			txt="Finding files..."
			self.btn_Import.set_sensitive(False)				
 		elif self.fileBrowseCount == 0:
			txt="No files found"
			self.btn_Import.set_sensitive(False)
		else:
			s = ""
			if self.fileBrowseCount >= backend.MAX_FILES_IN_THUMB_BROWSER:
				s = "more than "
			txt="Ready to import "+s+str(self.fileBrowseCount)+" files"
			self.btn_Import.set_sensitive(True)

		self.label_browser_status.set_label(txt)

	# toggles the widgets that are disabled when deleting photos
	# passing in "True" will enable widgets, "False" will disable them
	def showWhileDeleting(self, show_hide):
		self.hbuttonbox_buttons.set_sensitive(show_hide)
		self.chk_photos.set_sensitive(show_hide)
		self.chk_videos.set_sensitive(show_hide)
		self.photo_source_browser.set_sensitive(show_hide)
		self.iconview_thumb.set_sensitive(show_hide)
		self.button_delete_confirmation.set_visible(not show_hide)
		self.menuitem_prefs.set_visible(show_hide)
		
		if show_hide:
			self.eventbox_browser_status.modify_bg(gtk.STATE_NORMAL, None) # reset label color
			self.button_delete.set_label("Delete")
		else:
			self.eventbox_browser_status.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red")) # label color to red
			self.button_delete.set_label("Cancel")
	
	# returns a list of paths for the selected thumbnails
	def getSelectedFiles(self):
		filelist = []
		if not self.button_ShowOptions.get_active():
			return filelist

		selected = self.iconview_thumb.get_selected_items()
		if len(selected) > 0:
			for tupleIndex in selected:
				f = self.liststore_files[tupleIndex[0]]
				filelist.append(f)
		return filelist

	def fill_thumb_browser(self):
		self.fill_thumb_browser_has_run = True
		self.liststore_browser.clear()
		self.liststore_files = []
		self.label_browser_status.set_label("Finding files...");

		if self.browserThread and backend.FILE_BROWSE_RUNNING:
			self.numberBrowserThreadRestarts += 1
			backend.RESTART_THUMBS = True
		else:
			backend.FILE_BROWSE_RUNNING = True
			self.numberBrowserThreadRestarts = 0
			self.browserThread = BrowserThread(self);
			self.browserThread.start()

	def setImportRunningGUI(self):
		self.ImportRunning = True
		self.btn_Import.set_sensitive(False)
		self.btn_Cancel.set_label("Cancel")
		self.showThumbPreview()
		self.expander_metadata.hide()

	def setImportNotRunningGUI(self):
		self.ImportRunning = False
		self.btn_Cancel.set_label("Done")
		self.btn_Import.set_sensitive(True)
		self.main_progressbar.set_fraction(0.0)
		self.showReport()

	def showReport(self):
		self.thumbnail_preview.hide()
		self.vbox_report_log.show()

	def showThumbPreview(self):
		self.vbox_report_log.hide()
		self.thumbnail_preview.show()

			
	def clean_up(self):
		backend.QUIT_IMPORT = True
		backend.QUIT_THUMBS = True
	
	# for updating directory labels in the gui
	def photoLibraryPath(self, date=datetime.date.today()):
		path = os.path.join(backend.prefs["photoLibraryPath"])
		if self.prefs_chk_year.get_active():
			path = os.path.join(path, date.strftime("%Y"))
		try:
			path = os.path.join(path, date.strftime(self.prefs_entry_monthDir.get_text()))
		except:
			return ""
		if backend.GROUP_SUBDIR_NAME:
			path = os.path.join(path, backend.GROUP_SUBDIR_NAME)
		return path
		
		# for updating filename labels in the gui
	def labelFileName(self, name="photo", num = 1):
		string = name + self.prefs_entry_paddingSeparator.get_text()
		string += str(num).zfill(int(self.prefs_entry_numPadding.get_text()))
		string += '.' + backend.prefs["photoExtensions"][0] + '"' #uses first extension in prefs as example
		return string
	
	# called while filename is being modified
	def legalFilename(self, name):
		badchars = '\/:*?^"<>|'
		badNames = ('CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4',
					'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT1', 'LPT2',
					'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9')
					
		for c in badchars:
			name = name.replace(c,'')
		for s in badNames:
			if name.upper() == s: name = ''
		return name
		
	# called after filename is commited (leave focus, or press enter)
	# removes leading/trailing whitespace and any trailing '.'
	def legalFilenameHelper(self, name):
		name = name.strip() #removes leading and trailing whitespace
		while name.endswith(' ') or name.endswith('.'):
			name = name.rstrip('.')
			name = name.rstrip(' ')
		return name
			
	# Only for debugging
	def printPrefs(self, button):
		print "SubDir\t", backend.GROUP_SUBDIR_NAME
		for key, value in backend.prefs.items():
			print key, "\t", value
		print "==================================\n"
		
	# Initialization	
	def set_variables(self):
		if len(sys.argv) > 1 and os.path.isdir(sys.argv[1]):
			fList = os.listdir(sys.argv[1])
			if "DCIM" in fList and "Android" in fList:
				#Special check for Android devices
				backend.prefs["sourceDir"] = os.path.join(sys.argv[1],"DCIM")
			else:	
				backend.prefs["sourceDir"] = sys.argv[1]
		self.photo_library_firsttime = True
		self.photo_source_firsttime = True
		self.browserThread = None
		self.fileBrowseCount = None
		self.ImportRunning = False
		self.fill_thumb_browser_has_run = False
			
	def buildMainWindow(self, builder):	
		#Initialize global widgets
		self.window = builder.get_object("MainWindow")
		self.thumbnail_preview = builder.get_object("thumbnails")
		self.entry_rename = builder.get_object("entry_rename") # text entry box for renaming files when importing
		self.photo_library_browser = builder.get_object("photo_library")
		self.photo_source_browser = builder.get_object("photo_source")
		self.main_progressbar = builder.get_object("main_progressbar")
		self.chk_photos = builder.get_object("chk_photos")
		self.chk_videos = builder.get_object("chk_videos")
		self.chk_delete = builder.get_object("chk_delete")
		self.chk_rename = builder.get_object("chk_rename")
		self.chk_subDir = builder.get_object("chk_subDir")
		#self.entry_rename = builder.get_object("entry_rename") # duplicate
		self.entry_subDirName = builder.get_object("entry_subDirName")
		self.button_ShowOptions = builder.get_object("button_ShowOptions")
		self.label_subDir_text = builder.get_object("label_subDir_text")
		self.hbox_subDir_label = builder.get_object("hbox_subDir_label") # container for sub dir labels (needed for show/hide)
		self.eventbox_browser_status = builder.get_object("eventbox_browser_status") # allows color changes to browser label
		self.aboutdialog = builder.get_object("aboutdialog")
		self.expander_metadata = builder.get_object("expander_metadata")
		
		# Menu Items:
		self.menuitem_prefs = builder.get_object("menuitem_prefs")
		
		#Hidden widgets
		self.frame_browser = builder.get_object("frame_browser") 
		self.vbox_options = builder.get_object("vbox_options")
		self.menubar = builder.get_object("menubar")

		#buttons
		self.btn_Import = builder.get_object("btn_Import")
		self.btn_Cancel = builder.get_object("btn_Cancel")
		self.button_delete = builder.get_object("button_delete")
		self.button_delete_confirmation = builder.get_object("button_delete_confirmation")
		self.hbuttonbox_buttons = builder.get_object("hbuttonbox_buttons") # list of all main buttons (Import, cancel, show options). disabled when deleting photos
		
		
		self.label_browser_status = builder.get_object("label_browser_status")
		self.label_report_log = builder.get_object("label_report_log")
		self.label_report_title = builder.get_object("label_report_title")
		self.label_thumb_caption = builder.get_object("label_thumb_caption")
		
		self.vbox_report_log = builder.get_object("vbox_report_log")
		
		# set up thumbnail browser	
		self.liststore_browser = builder.get_object("liststore_browser")
		self.iconview_thumb = builder.get_object("iconview_thumb")
		

	def buildPrefsWindow(self, builder):
		#Initialize Preference Dialog:
		self.dialog_preferences = builder.get_object("dialog_preferences")
		self.prefs_entry_imageExtensions = builder.get_object("prefs_entry_imageExtensions")
		self.prefs_entry_videoExtensions = builder.get_object("prefs_entry_videoExtensions")
		self.prefs_entry_numPadding = builder.get_object("prefs_entry_numPadding")
		self.prefs_entry_paddingSeparator = builder.get_object("prefs_entry_paddingSeparator")
		self.prefs_label_DirPath_text = builder.get_object("prefs_label_DirPath_text")
		self.prefs_entry_monthDir = builder.get_object("prefs_entry_monthDir")
		self.prefs_chk_year = builder.get_object("prefs_chk_year")
		self.prefs_button_savePrefs = builder.get_object("prefs_button_savePrefs")
			
	
	def __init__(self):
		builder = gtk.Builder()
		builder.add_from_file(os.path.join(PROJECT_ROOT,"gui-gtk.glade"))

		self.set_variables()
		self.buildMainWindow(builder)
				
		#Set Main Window settings:
		list=backend.findFiles(backend.prefs["sourceDir"], justOne=True)
		if list and len(list) > 0:
			self.label_browser_status.set_label("Ready to import to: "+backend.prefs["photoLibraryPath"])
		else:
			self.label_browser_status.set_label("Nothing to import")
			self.btn_Import.set_sensitive(False)
	
		self.label_report_title.set_label("Current Settings:")	
		stat = "\nSource:\n" + backend.prefs["sourceDir"] + "\n\nDestination:\n" + backend.prefs["photoLibraryPath"]
		if backend.prefs["deleteMedia"]:
			stat += "\n\nDelete files from device after successful import"
		else:
			stat += "\n\nLeave photos on device after import"
		self.label_report_log.set_label(stat)

		# set global widgets options
		self.photo_library_browser.set_current_folder(backend.prefs["photoLibraryPath"])
		self.photo_source_browser.set_current_folder(backend.prefs["sourceDir"])

		self.chk_photos.set_active(backend.prefs["importPhotos"])
		self.chk_videos.set_active(backend.prefs["importVideos"])
		self.chk_delete.set_active(backend.prefs["deleteMedia"])
		self.chk_rename.set_active(backend.prefs["rename"])
		self.entry_rename.set_text(backend.prefs["renameString"])

		# set up thumbnail browser	
		self.iconview_thumb.set_text_column(0)
		self.iconview_thumb.set_pixbuf_column(1)		
		
		# Prefs:
		self.buildPrefsWindow(builder)		
		
		#Set Preferences Widgets:
		if backend.prefs["rename"]: self.on_chk_rename_toggled(self.chk_rename) #Make rename box visible if pref is checked
		self.prefs_entry_imageExtensions.set_text(backend.stringTuple(backend.prefs["photoExtensions"]))
		self.prefs_entry_videoExtensions.set_text(backend.stringTuple(backend.prefs["videoExtensions"]))
		self.prefs_entry_numPadding.set_text(str(backend.prefs["renameStringNumPadding"]))
		self.prefs_entry_paddingSeparator.set_text(backend.prefs["renameStringNumPaddingSeparator"])
		self.prefs_entry_paddingSeparator.set_text(backend.prefs["renameStringNumPaddingSeparator"])
		self.prefs_entry_monthDir.set_text(backend.prefs["monthDirFormat"])
		self.prefsUpdatePathLabels() # initial string for dir label
		self.prefs_button_savePrefs.set_sensitive(False) #disable 'save prefs' button
		
		builder.connect_signals(self)
						
if __name__ == "__main__":		
	win = GUI()
	win.window.show_all()
	gtk.main()
	
	

